package com.liushao.service.impl;

import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.liushao.entity.Lend;
import com.liushao.entity.LendItem;
import com.liushao.entity.LendItemReturn;
import com.liushao.entity.LendReturn;
import com.liushao.entity.bo.TransFlowBO;
import com.liushao.enums.LendStatusEnum;
import com.liushao.enums.TransTypeEnum;
import com.liushao.hfb.FormHelper;
import com.liushao.hfb.HfbConst;
import com.liushao.hfb.RequestHelper;
import com.liushao.mapper.*;
import com.liushao.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.liushao.util.LendNoUtils;
import com.sun.tools.internal.xjc.reader.dtd.bindinfo.BIElement;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * <p>
 * 还款记录表 服务实现类
 * </p>
 *
 * @author chen
 * @since 2025-01-03
 */
@Service
public class LendReturnServiceImpl extends ServiceImpl<LendReturnMapper, LendReturn> implements LendReturnService {


    @Autowired
    private UserAccountService userAccountService;

    @Autowired
    private UserAccountMapper userAccountMapper;

    @Autowired
    private LendItemMapper lendItemMapper;



    @Autowired
    private UserBindService userBindService;

    @Autowired
    private LendMapper lendMapper;

    @Autowired
    private LendItemReturnService lendItemReturnService;

    @Autowired
    private TransFlowService transFlowService;

    @Autowired
    private LendItemReturnMapper lendItemReturnMapper;


    @Override
    public List<LendReturn> selectLendById(Long lendId) {

        QueryWrapper<LendReturn> wrapper = new QueryWrapper<>();
        wrapper.eq("lend_id",lendId);
        List<LendReturn> lendReturnList = baseMapper.selectList(wrapper);

        return lendReturnList;
    }

    @Override
    public String commitReturn(Long lendReturnId, Long userId) {
         //还款记录
        LendReturn lendReturn = baseMapper.selectById(lendReturnId);
        //判断账户余额是否充足
        BigDecimal account = userAccountService.getAccountById(userId);
        //判断自己写

        //获取借款人 code
        String bindCode = userBindService.getBindCodeByUserId(userId);

        //获取lend
        Long lendId = lendReturn.getLendId();
        Lend lend = lendMapper.selectById(lendId);



        Map<String,Object> map = new HashMap<>();
        map.put("agentId", HfbConst.AGENT_ID);//给商户分配的唯一标识
        map.put("agentGoodsName",lend.getTitle());//商户商品名称
        map.put("agentBatchNo",lendReturn.getReturnNo());//批次号
        map.put("fromBindCode",bindCode);//还款人绑定协议号
        map.put("totalAmt",lendReturn.getTotal());//还款总额
        map.put("note","");//备注
        List<Map<String,Object>> lendItemReturnDetailList= lendItemReturnService.addReturnDetail(lendReturnId);

        map.put("data", JSONObject.toJSONString(lendItemReturnDetailList));//还款明细数据，json格式。目前一次最多支持100个单。


        map.put("voteFeeAmt",new BigDecimal("0"));
        /*
        	string	255	是	还款扣款完成后，扣款结果同步返回到商户的完整地址
	string	255	是	换款扣款完成后，异步通知商户扣款结果
	long		是	时间戳。从1970-01-01 00:00:00算起的毫秒数。
	string	32	是	验签参数。
         */
        map.put("returnUrl",HfbConst.BORROW_RETURN_RETURN_URL);
        map.put("notifyUrl",HfbConst.BORROW_RETURN_NOTIFY_URL);
        map.put("timestamp",new Date().getTime());
        map.put("sign", RequestHelper.getSign(map));

        String formStr = FormHelper.buildForm(HfbConst.BORROW_RETURN_URL, map);

        return formStr;
    }
@Transactional(rollbackFor = Exception.class)
    @Override
    public void notifyss(Map<String, Object> objectMap) {

        System.out.println("还款成功了...");
           //批次号
       String agentBatchNo= (String) objectMap.get("agentBatchNo");
        boolean result = transFlowService.isSaveTransFlow(agentBatchNo);

        if(result){
            System.out.println("违反了幂等性了...");
            return;
        }

        //获取还款数据
        String voteFeeAmt= (String) objectMap.get("voteFeeAmt");// 手续费
        QueryWrapper<LendReturn> wrapper = new QueryWrapper<>();
        wrapper.eq("return_no",agentBatchNo);
        LendReturn lendReturn = baseMapper.selectOne(wrapper);

        lendReturn.setStatus(1);//更新还款状态
        lendReturn.setFee(new BigDecimal(voteFeeAmt));//手续费
        lendReturn.setRealReturnTime(new Date());
        baseMapper.updateById(lendReturn);
        //更新标的信息
       Lend lend = lendMapper.selectById(lendReturn.getLendId());
       //最后一次还款需要更新标的状态
        if(lendReturn.getLast()){
              lend.setStatus(LendStatusEnum.PAY_OK.getStatus());//标的结清了
              lendMapper.updateById(lend);
        }

      //借款账号需要向外转钱

    BigDecimal totalAmt = new BigDecimal((String) objectMap.get("totalAmt"));

    String bindCode = userBindService.getBindCodeByUserId(lend.getUserId());

  userAccountMapper.updateUserAccount(bindCode,totalAmt.negate(),new BigDecimal(0));

  /*
       private String agentBillNo;//商户充值订单号
    private BigDecimal amount;//账户的可用余额
    private String bindCode;//绑定
    private TransTypeEnum transTypeEnum;//绑定协议号
    private String memo;//备忘
   */

    TransFlowBO transFlowBO = new TransFlowBO(
            agentBatchNo,
            totalAmt,
            bindCode,
            TransTypeEnum.RETURN_DOWN,
            "借款人还款，项目编号是:"+lend.getLendNo()
    );

    transFlowService.saveTransFlow(transFlowBO);


    //你一还款   对于投资人而言 就会产生回款信息
    List<LendItemReturn> lendItemReturnList =
            lendItemReturnService.selectLendItemReturnList(lendReturn.getId());

    lendItemReturnList.forEach(item->{
        //更新回款状态
        item.setStatus(1);
        item.setRealReturnTime(new Date());
        lendItemReturnMapper.updateById(item);

        //更新出借信息
        LendItem lendItem = lendItemMapper.selectById(item.getLendItemId());

        lendItem.setRealAmount(item.getInvestAmount());
        lendItemMapper.updateById(lendItem);

        //投资账号转入金额
        String investBindCode= userBindService.getBindCodeByUserId(item.getInvestUserId());
        userAccountMapper.updateUserAccount(investBindCode,item.getTotal(),new BigDecimal(0));

        TransFlowBO transFlowBO1 = new TransFlowBO(
                LendNoUtils.getReturnItemNo(),
                item.getTotal(),
                investBindCode,
                TransTypeEnum.INVEST_BACK,
                "还款到账，项目编号是:"+lend.getLendNo()
        );

        transFlowService.saveTransFlow(transFlowBO1);


    });


}
}
